package com.learn.dept.controller;

import com.learn.dept.service.DeptService;
import com.learn.model.Dept;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/hystrix")
public class HystrixController {
    @Autowired
    private DeptService deptService;
    
    /*
     * @HystrixCommand：开启后备模式
     *  · fallbackMethod：配置当前请求失败时调用的备选方法，该备选方法必须在当前类
     *  · threadPoolKey：配置线程池标识，Hystrix会按照默认配置初始化该线程池
     *  · threadPoolProperties：修改线程池默认配置。线程池大小计算公式：每秒处理请求的峰值 × 99%平均响应时间 + 缓冲线程数
     *      · maxQueueSize为-1时，使用SynchronousQueue实现队列，即同步对列
     *      · maxQueueSize大于1时，使用LinkedBlockingQueue实现队列
     */
    @PostMapping("/findOneDept")
    @HystrixCommand(
            fallbackMethod = "findOneDeptFail",
            threadPoolKey = "deptThreadPool",
            threadPoolProperties = {
                    @HystrixProperty(name = "coreSize", value = "10"),
                    @HystrixProperty(name = "maxQueueSize", value = "10")
            }
    )
    public Dept findOneDept(Integer id) {
        Dept dept = deptService.findOnedept(id);
        
        if (dept == null) {
            throw new RuntimeException("ID为 " + id + " 的部门不存在");
        }
        
        return dept;
    }
    
    /**
     * 后备模式中的备选方法，除了方法名和方法体其他的需要和原方法一样
     */
    public Dept findOneDeptFail(Integer id) {
        // return "{\"code\": 500, \"msg\": \"ID为 " + id + " 的部门不存在\"}";
        return new Dept().setId(id).setName("ID为 " + id + " 的部门不存在");
    }
}
